'''
Created on 17/03/2011

@author: Renzo Nuccitelli
'''
import unittest
from ce.convertion.field import RequiredField, EmailField, FieldsDescriptor, \
    ERROR_MSGS, LinkField, BrPhoneField, CepField, BooleanField,\
    RealCurrencyField, IntField, RadioStringField, MultipleStringField
from google.appengine.ext import db


class Stub(object):
    pass

class RequiredFieldTests(unittest.TestCase):
    def testRequiredValidade(self):
        bf = RequiredField(label = "lbl")
        self.assertEqual(ERROR_MSGS["requiredField"], bf.validate(None))
        self.assertEqual(ERROR_MSGS["requiredField"], bf.validate(""))
        bf.required = False
        self.assertEqual(None, bf.validate(None))
        self.assertEqual(None, bf.validate(""))

    def testTransformToModel (self):
        bf = RequiredField(label = "lbl")
        self.assertEqual("value", bf.transformToModel("value"))
        bf.toModelTransform = lambda v: v.upper()
        self.assertEqual("VALUE", bf.transformToModel("value"))

    def testTransformFromModel(self):
        bf = RequiredField(label = "lbl")
        self.assertEqual("VALUE", bf.transformFromModel("VALUE"))
        bf.fromModelTransform = lambda v: v.lower()
        self.assertEqual("value", bf.transformFromModel("VALUE"))


class EmailFieldTests(unittest.TestCase):
    def testValidade(self):
        bf = EmailField(label = "lbl")
        self.assertEqual(ERROR_MSGS["requiredField"], bf.validate(""))
        self.assertEqual(ERROR_MSGS["requiredField"], bf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidMail"], bf.validate("www.com.br"))
        self.assertEqual(ERROR_MSGS["invalidMail"], bf.validate("www@"))
        self.assertEqual(None, bf.validate("www@com.br"))
        self.assertEqual(None, bf.validate("www@balh.com.br"))
        bf.required = False
        self.assertEqual(None, bf.validate(""))
        self.assertEqual(None, bf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidMail"], bf.validate("www.com.br"))
        self.assertEqual(ERROR_MSGS["invalidMail"], bf.validate("www@"))
        self.assertEqual(None, bf.validate("www@com.br"))
        self.assertEqual(None, bf.validate("www@balh.com.br"))

class LinkFieldTests(unittest.TestCase):
    def testToModelTransform(self):
        lf = LinkField(label = "balh")
#        self.assertEqual("http://www.balh.ks", lf.transformToModel("www.balh.ks"))


    def testValidate(self):
        lf = LinkField(label = "balh")
#        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(""))
#        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(None))
#        self.assertEqual(ERROR_MSGS["invalidLink"], lf.validate("www"))
#        self.assertEqual(ERROR_MSGS["invalidLink"], lf.validate("www@"))
#        self.assertEqual(None, lf.validate("www.blah.com.br"))
#        lf.required = False
#        self.assertEqual(None, lf.validate(""))
#        self.assertEqual(None, lf.validate(None))
#        self.assertEqual(ERROR_MSGS["invalidLink"], lf.validate("www"))
#        self.assertEqual(ERROR_MSGS["invalidLink"], lf.validate("www@"))
#        self.assertEqual(None, lf.validate("www.blah.com.br"))

class BrPhoneTests(unittest.TestCase):
    def testToModelTransform(self):
        lf = BrPhoneField(label = "balh")
        self.assertEqual("1234567890", lf.transformToModel("(12) 3456-7890"))

    def testFromModelTransform(self):
        lf = BrPhoneField(label = "balh")
        self.assertEqual("(12) 3456-7890", lf.transformFromModel("1234567890"))


    def testValidate(self):
        lf = BrPhoneField(label = "balh")
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(""))
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidBrPhone"], lf.validate("(12) 3456-789"))
        self.assertEqual(ERROR_MSGS["invalidBrPhone"], lf.validate("(12) 3456-78901"))
        self.assertEqual(ERROR_MSGS["invalidBrPhone"], lf.validate("(12) 3456-789A"))
        self.assertEqual(None, lf.validate("(12) 3456-7890"))
        lf.required = False
        self.assertEqual(None, lf.validate(""))
        self.assertEqual(None, lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidBrPhone"], lf.validate("(12) 3456-789"))
        self.assertEqual(ERROR_MSGS["invalidBrPhone"], lf.validate("(12) 3456-78901"))
        self.assertEqual(ERROR_MSGS["invalidBrPhone"], lf.validate("(12) 3456-789A"))
        self.assertEqual(None, lf.validate("(12) 3456-7890"))


class CepTests(unittest.TestCase):
    def testToModelTransform(self):
        lf = CepField(label = "balh")
        self.assertEqual("12345678", lf.transformToModel("12345-678"))

    def testFromModelTransform(self):
        lf = CepField(label = "balh")
        self.assertEqual("12345-678", lf.transformFromModel("12345678"))


    def testValidate(self):
        lf = CepField(label = "balh")
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(""))
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidCep"], lf.validate("123456-789"))
        self.assertEqual(ERROR_MSGS["invalidCep"], lf.validate("12345-78901"))
        self.assertEqual(ERROR_MSGS["invalidCep"], lf.validate("123-45789"))
        self.assertEqual(None, lf.validate("12345-678"))
        lf.required = False
        self.assertEqual(None, lf.validate(""))
        self.assertEqual(None, lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidCep"], lf.validate("123456-789"))
        self.assertEqual(ERROR_MSGS["invalidCep"], lf.validate("12345-78901"))
        self.assertEqual(ERROR_MSGS["invalidCep"], lf.validate("123-45789"))
        self.assertEqual(None, lf.validate("12345-678"))
        
class BooleanTests(unittest.TestCase):
    def testToModelTransform(self):
        lf = BooleanField(label = "balh")
        self.assertEqual(True, lf.transformToModel("True"))
        self.assertEqual(True, lf.transformToModel("true"))
        self.assertEqual(False, lf.transformToModel("False"))
        self.assertEqual(False, lf.transformToModel("false"))

    def testFromModelTransform(self):
        lf = BooleanField(label = "balh")
        self.assertEqual("True", lf.transformFromModel(True))
        self.assertEqual("False", lf.transformFromModel(False))


    def testValidate(self):
        lf = BooleanField(label = "balh")
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(""))
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidBoolean"], lf.validate("w"))
        self.assertEqual(ERROR_MSGS["invalidBoolean"], lf.validate("ss"))
        self.assertEqual(ERROR_MSGS["invalidBoolean"], lf.validate("kk"))
        self.assertEqual(None, lf.validate("true"))
        self.assertEqual(None, lf.validate("false"))
        lf.required = False
        self.assertEqual(None, lf.validate(""))
        self.assertEqual(None, lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidBoolean"], lf.validate("w"))
        self.assertEqual(ERROR_MSGS["invalidBoolean"], lf.validate("ss"))
        self.assertEqual(ERROR_MSGS["invalidBoolean"], lf.validate("kk"))
        self.assertEqual(None, lf.validate("true"))
        self.assertEqual(None, lf.validate("false"))


class RealCurrencyTests(unittest.TestCase):
    def testToModelTransform(self):
        lf = RealCurrencyField(label = "balh")
        self.assertEqual(1212.71, lf.transformToModel("1.212,71"))
        self.assertEqual(2121212.71, lf.transformToModel("2.121.212,71"))

    def testFromModelTransform(self):
        lf = RealCurrencyField(label = "balh")
        self.assertEqual("1.212,71", lf.transformFromModel(1212.71))
        self.assertEqual("1.212,70", lf.transformFromModel(1212.7))
        self.assertEqual("1.212,00", lf.transformFromModel(1212))
        self.assertEqual("1.212.121.212,80", lf.transformFromModel(1212121212.8))
        
    def testValidate(self):
        lf = RealCurrencyField(label = "balh")
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(""))
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidRealCurrency"], lf.validate("w"))
        self.assertEqual(ERROR_MSGS["invalidRealCurrency"], lf.validate("0.1,2s"))
        self.assertEqual(ERROR_MSGS["invalidRealCurrency"], lf.validate("1.222,00k"))
        self.assertEqual(None, lf.validate("1.212,71"))
        lf.required = False
        self.assertEqual(None, lf.validate(""))
        self.assertEqual(None, lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidRealCurrency"], lf.validate("w"))
        self.assertEqual(ERROR_MSGS["invalidRealCurrency"], lf.validate("0.1,2s"))
        self.assertEqual(ERROR_MSGS["invalidRealCurrency"], lf.validate("1.222,00k"))
        self.assertEqual(None, lf.validate("1.212,71"))
        
class IntTests(unittest.TestCase):
    def testToModelTransform(self):
        lf = IntField(label = "balh")
        self.assertEqual(1212, lf.transformToModel("1212"))
        self.assertEqual(2121212, lf.transformToModel("2121212"))

    def testFromModelTransform(self):
        lf = IntField(label = "balh")
        self.assertEqual("121271", lf.transformFromModel(121271))
        self.assertEqual("12127", lf.transformFromModel(12127))

    def testValidate(self):
        lf = IntField(label = "balh")
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(""))
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidInt"], lf.validate("w"))
        self.assertEqual(ERROR_MSGS["invalidInt"], lf.validate("0.1,2s"))
        self.assertEqual(ERROR_MSGS["invalidInt"], lf.validate("1.222,00"))
        self.assertEqual(None, lf.validate("121271"))
        lf.required = False
        self.assertEqual(None, lf.validate(""))
        self.assertEqual(None, lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidInt"], lf.validate("w"))
        self.assertEqual(ERROR_MSGS["invalidInt"], lf.validate("0.1,2s"))
        self.assertEqual(ERROR_MSGS["invalidInt"], lf.validate("1.222,00"))
        self.assertEqual(None, lf.validate("121271"))
        

class RadioStringFieldTests(unittest.TestCase):
    def testValidate(self):
        lf = RadioStringField(label = "balh",choices=["choice1","choice2"])
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(""))
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidChoice"], lf.validate("w"))
        self.assertEqual(ERROR_MSGS["invalidChoice"], lf.validate("0.1,2s"))
        self.assertEqual(ERROR_MSGS["invalidChoice"], lf.validate("choice"))
        self.assertEqual(None, lf.validate("choice1"))
        self.assertEqual(None, lf.validate("choice2"))
        lf.required = False
        self.assertEqual(None, lf.validate(""))
        self.assertEqual(None, lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidChoice"], lf.validate("w"))
        self.assertEqual(ERROR_MSGS["invalidChoice"], lf.validate("0.1,2s"))
        self.assertEqual(ERROR_MSGS["invalidChoice"], lf.validate("choice"))
        self.assertEqual(None, lf.validate("choice1"))
        self.assertEqual(None, lf.validate("choice2"))
        
class MultipleStringFieldTests(unittest.TestCase):
    def testValidate(self):
        lf = MultipleStringField( "balh",["Escolha 1","Escolha 2"],choices=["choice1","choice2"])
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate([]))
        self.assertEqual(ERROR_MSGS["requiredField"], lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidChoices"], lf.validate(["w"]))
        self.assertEqual(ERROR_MSGS["invalidChoices"], lf.validate("0.1,2s"))
        self.assertEqual(ERROR_MSGS["invalidChoices"], lf.validate(["choice"]))
        self.assertEqual(None, lf.validate(["choice1"]))
        self.assertEqual(None, lf.validate(["choice2"]))
        self.assertEqual(None, lf.validate(["choice2","choice1"]))
        lf.required = False
        self.assertEqual(None, lf.validate([]))
        self.assertEqual(None, lf.validate(None))
        self.assertEqual(ERROR_MSGS["invalidChoices"], lf.validate(["w"]))
        self.assertEqual(ERROR_MSGS["invalidChoices"], lf.validate("0.1,2s"))
        self.assertEqual(ERROR_MSGS["invalidChoices"], lf.validate(["choice"]))
        self.assertEqual(None, lf.validate(["choice1"]))
        self.assertEqual(None, lf.validate(["choice2"]))
        self.assertEqual(None, lf.validate(["choice2","choice1"]))




class ModelStub(db.Model):
    email = db.EmailProperty()
    email2 = db.EmailProperty(required = True)


class FieldsDescriptorStub(FieldsDescriptor):
    def __init__(self):
        super(FieldsDescriptorStub, self).__init__(ModelStub)

    def fields(self):
        return ({ "email2":"Email"}, {"email":"Email"})


class FieldsDescriptorTests(unittest.TestCase):
    def testToField(self):
        descriptor = FieldsDescriptorStub()
        field = descriptor.toField(ModelStub, "email", "Email");
        self.assertTrue(isinstance(field, EmailField))
        self.assertFalse(field.required)
        self.assertEqual("Email", field.label)
        field = descriptor.toField(ModelStub, "email2", "Email");
        self.assertTrue(isinstance(field, EmailField))
        self.assertTrue(field.required)
        self.assertEqual("Email", field.label)

    def testValidade(self):
        descriptor = FieldsDescriptorStub()
        self.assertEqual({"email2":ERROR_MSGS["requiredField"]}, descriptor.validate(email = "", email2 = ""))
        self.assertEqual({"email":ERROR_MSGS["invalidMail"], "email2":ERROR_MSGS["requiredField"]}, descriptor.validate(email = "www", email2 = ""))
        self.assertEqual({}, descriptor.validate(email = "v@bla.com", email2 = "v@bla.com"))

    def testBuildModelPropertiesDict (self):
        descriptor = FieldsDescriptorStub()
        d = descriptor.buildModelPropertiesDict(email = "", email2 = "v@bla.com")
        self.assertEqual({"email" : None, "email2" : "v@bla.com"}, d)

    def testSetModelProperties(self):
        modelStub = ModelStub(email = "mail1@bl.com", email2 = "mail2@bla.com")
        descriptor = FieldsDescriptorStub()
        descriptor.setModelPropertiesDict(modelStub, email = "m1@com.br", email2 = "m2@com.br")
        self.assertEqual("m2@com.br", modelStub.email2)
        self.assertEqual("m1@com.br", modelStub.email)

    def testBuildFieldValuesDict(self):
        modelStub = ModelStub(email = "mail1@com.br", email2 = "mail2@com.br")
        descriptor = FieldsDescriptorStub()
        d = descriptor.buildFieldValuesDict(modelStub)
        self.assertEqual({"email" : "mail1@com.br", "email2" : "mail2@com.br"}, d)


if __name__ == "__main__":
    unittest.main()
